﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.ComponentModel;
using System.Windows.Input;
using System.Windows.Navigation;
using Halfwit.Views;
using System.Windows.Controls;
using TweetSharp.Twitter.Extensions;
using TweetSharp.Twitter.Fluent;
using TweetSharp.Twitter.Model;
using TweetSharp.Model;

namespace Halfwit.ViewModels
{
    public class LoginViewModel : INotifyPropertyChanged
    {
        public LoginViewModel(Action onSuccess)
        {
            Title = "Connection";

            _onSuccess = onSuccess;

            this.RequestPin = new RelayCommand("Request PIN", FetchPin);
            this.Save = new RelayCommand("Save", AuthenticateAndSave, CanAuthenticate);
            this.Cancel = new RelayCommand("Cancel", GoBackOrQuit);
        }

        private Action _onSuccess;
        private string _pin = String.Empty;
        private OAuthToken _requestToken;

        private void FetchPin(object o)
        {
            // get an authenticated request token from twitter
            _requestToken = GetRequestToken(Properties.Settings.Default.ConsumerKey, Properties.Settings.Default.ConsumerSecret);
            if (_requestToken == null) return;

            // automatically starts the default web browser, sending the 
            // user to the authorization URL.
            FluentTwitter.CreateRequest()
                .Authentication
                .AuthorizeDesktop(Properties.Settings.Default.ConsumerKey, Properties.Settings.Default.ConsumerSecret, _requestToken.Token);
        }

        private void GoBackOrQuit(object o)
        {
            var ns = NavigationService.GetNavigationService(Owner);
            if (ns == null) return;

            if (!ns.CanGoBack)
            {
                App.Current.Shutdown();
                return;
            }

            ns.GoBack();
        }

        private bool CanAuthenticate(object o)
        {
            return _requestToken != null;
        }

        private void AuthenticateAndSave(object o)
        {
            if (_requestToken == null) return;

            var ns = NavigationService.GetNavigationService(Owner);
            if (ns == null) return;

            // exchange the unauthenticated request token with an authenticated access token,
            // and remember to persist this authentication pair for future use

            var accessToken = FluentTwitter.CreateRequest()
                .Authentication
                .GetAccessToken(Properties.Settings.Default.ConsumerKey, Properties.Settings.Default.ConsumerSecret, _requestToken.Token, Pin);

            var response = accessToken.Request();
            var result = response.AsToken();
            if (result == null || String.IsNullOrEmpty(result.Token))
            {
                var error = response.AsError();
                MessageBox.Show(error.ErrorMessage);
                return;
            }

            // make an authenticated call to Twitter with the token and secret
            Properties.Settings.Default.AccessToken = result.Token;
            Properties.Settings.Default.AccessTokenSecret = result.TokenSecret;

            if (!TwitterConnection.Authenticate())
            {
                MessageBox.Show("There was a problem authenticating. Please try restarting Halfwit.");
                Application.Current.Shutdown();
            }

            //var verify = FluentTwitter.CreateRequest()
            //    .AuthenticateWith(Properties.Settings.Default.ConsumerKey, Properties.Settings.Default.ConsumerSecret, result.Token, result.TokenSecret)
            //    .Account()
            //    .VerifyCredentials();

            //response = verify.Request();
            //var identity = response.AsUser();
            //if (identity == null)
            //{
            //    var error = response.AsError();
            //    MessageBox.Show(error.ErrorMessage);
            //    return;
            //}

            Properties.Settings.Default.Save();

            _onSuccess();
        }

        public string Title { get; private set; }
        public DependencyObject Owner { get; set; }
        public ICommand RequestPin { get; private set; }
        public ICommand Save { get; private set; }
        public ICommand Cancel { get; private set; }

        public string Pin
        {
            get { return _pin.Trim(); }
            set
            {
                _pin = value;
                OnPropertyChanged("Pin");
            }
        }


        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        #region OAuth Helper Methods

        private static TweetSharp.Model.OAuthToken GetRequestToken(string consumerKey, string consumerSecret)
        {
            //var credentials = new OAuthCredentials
            //{
            //    Type = OAuthType.RequestToken,
            //    SignatureMethod = OAuthSignatureMethod.HmacSha1,
            //    ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader,
            //    ConsumerKey = "ConsumerKey",
            //    ConsumerSecret = "ConsumerSecret",
            //};

            //var client = new RestClient
            //{
            //    Authority = "http://twitter.com/oauth",
            //    Credentials = credentials,
            //};

            //var request = new RestRequest
            //{
            //    Path = "request_token"
            //};

            //RestResponse response = client.Request(request);





            var requestToken = FluentTwitter.CreateRequest()
                .Authentication
                .GetRequestToken(consumerKey, consumerSecret);

            var response = requestToken.Request();

            var result = response.AsToken();
            if (result != null) return result;

            var error = response.AsError();

            var mesg = error != null ? error.ErrorMessage
                : !String.IsNullOrEmpty(response.ResponseHttpStatusDescription) ? response.ResponseHttpStatusDescription
                : "Unknown error. Possible space-time continuum anomaly.";

            MessageBox.Show(mesg);
            return null;

            //System.Net.Configuration.DefaultProxySection s;
            //s.Proxy.AutoDetect
        }

        #endregion
    }
}
